package org.jsola.hr.service.impl;

import org.jsola.core.Page;
import org.jsola.hr.common.ExampleKit;
import org.jsola.hr.constant.HrConstants;
import org.jsola.hr.dao.IAttendGoOutRecordDAO;
import org.jsola.hr.dto.AttendGoOutRecordAddDTO;
import org.jsola.hr.dto.AttendGoOutRecordUpdateDTO;
import org.jsola.hr.entity.AttendGoOutRecordDO;
import org.jsola.hr.query.AttendGoOutRecordQuery;
import org.jsola.hr.service.IAttendGoOutRecordService;
import org.jsola.hr.vo.AttendGoOutRecordListVO;
import org.jsola.hr.vo.AttendGoOutRecordVO;
import org.jsola.user.core.TokenUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author zhr
 */
@Service("hrAttendGoOutRecordServiceImpl")
public class AttendGoOutRecordServiceImpl implements IAttendGoOutRecordService {

    @Autowired
    private IAttendGoOutRecordDAO attendGoOutRecordDAO;

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public AttendGoOutRecordVO save(AttendGoOutRecordAddDTO attendGoOutRecordAddDTO, TokenUser tokenUser) {
        // 转DO
        AttendGoOutRecordDO attendGoOutRecordDO = attendGoOutRecordAddDTO.to(AttendGoOutRecordDO.class);
        // 保存
        attendGoOutRecordDO = save(attendGoOutRecordDO, tokenUser.getSiteId(), tokenUser.getUserId());
        return attendGoOutRecordDO.to(AttendGoOutRecordVO.class);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int update(AttendGoOutRecordUpdateDTO attendGoOutRecordUpdateDTO, TokenUser tokenUser) {
        //转DO
        AttendGoOutRecordDO attendGoOutRecordDO = attendGoOutRecordUpdateDTO.to(AttendGoOutRecordDO.class);
        //根据主键更新，只更新非null值
        return updateByIdSelective(attendGoOutRecordDO, tokenUser.getSiteId(), tokenUser.getUserId());
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int deleteByIds(TokenUser tokenUser, String... attendGoOutRecordIds) {
        return logicalDeleteByIds(tokenUser.getSiteId(), tokenUser.getUserId(), (Object[]) attendGoOutRecordIds);
    }


    @Override
    public AttendGoOutRecordVO selectById(String attendGoOutRecordId, String siteId) {
        AttendGoOutRecordDO attendGoOutRecordDO = selectDOById(attendGoOutRecordId, siteId);
        if (attendGoOutRecordDO == null) {
            return null;
        }
        return attendGoOutRecordDO.to(AttendGoOutRecordVO.class);
    }

    @Override
    public List<AttendGoOutRecordListVO> select(AttendGoOutRecordQuery attendGoOutRecordQuery, String siteId) {
        List<AttendGoOutRecordDO> attendGoOutRecordDOList = selectDO(attendGoOutRecordQuery, siteId);
        if(CollectionUtils.isEmpty(attendGoOutRecordDOList)) {
            return attendGoOutRecordDOList == null ? null : new ArrayList<>();
        }
        return attendGoOutRecordDOList.stream()
                .map(attendGoOutRecordDO -> attendGoOutRecordDO.to(AttendGoOutRecordListVO.class))
                .collect(Collectors.toList());
    }

    @Override
    public int selectCount(AttendGoOutRecordQuery attendGoOutRecordQuery, String siteId) {
        Example example = buildExample(attendGoOutRecordQuery,siteId);
        return attendGoOutRecordDAO.selectCountByExample(example);
    }

    @Override
    public Page<AttendGoOutRecordListVO> selectPage(AttendGoOutRecordQuery attendGoOutRecordQuery, String siteId) {
        Example example = buildExample(attendGoOutRecordQuery,siteId);
        Page<AttendGoOutRecordDO> page = attendGoOutRecordDAO.selectPageByExample(example,
                attendGoOutRecordQuery.getPageNo(),
                attendGoOutRecordQuery.getPageSize());

        return page.to(AttendGoOutRecordListVO.class);
    }

    @Override
    public AttendGoOutRecordDO selectDOById(String attendGoOutRecordId, String siteId) {
        return listById(attendGoOutRecordId, siteId);
    }

    @Override
    public List<AttendGoOutRecordDO> selectDO(AttendGoOutRecordQuery attendGoOutRecordQuery, String siteId) {
        Example example = buildExample(attendGoOutRecordQuery,siteId);
        return attendGoOutRecordDAO.selectByExample(example);
    }


    /**
     * 根据查询参数，构建example

     * @param attendGoOutRecordQuery 查询参数
     * @param siteId 所属站点id
     * @return example
     */
    private Example buildExample(AttendGoOutRecordQuery attendGoOutRecordQuery, String siteId) {
        Example example = new Example(AttendGoOutRecordDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);
        if (attendGoOutRecordQuery.getCompanyId() != null) {
            example.and().andLike("companyId", "%" + attendGoOutRecordQuery.getCompanyId() + "%");
        }
        if (attendGoOutRecordQuery.getCompanyName() != null) {
            example.and().andLike("companyName", "%" + attendGoOutRecordQuery.getCompanyName() + "%");
        }
        if (attendGoOutRecordQuery.getDeptId() != null) {
            example.and().andLike("deptId", "%" + attendGoOutRecordQuery.getDeptId() + "%");
        }
        if (attendGoOutRecordQuery.getDeptName() != null) {
            example.and().andLike("deptName", "%" + attendGoOutRecordQuery.getDeptName() + "%");
        }
        if (attendGoOutRecordQuery.getEmpInfoId() != null) {
            example.and().andLike("empInfoId", "%" + attendGoOutRecordQuery.getEmpInfoId() + "%");
        }
        if (attendGoOutRecordQuery.getEmpInfoName() != null) {
            example.and().andLike("empInfoName", "%" + attendGoOutRecordQuery.getEmpInfoName() + "%");
        }
        if (attendGoOutRecordQuery.getYearly() != null) {
            example.and().andEqualTo("yearly", attendGoOutRecordQuery.getYearly());
        }
        if (attendGoOutRecordQuery.getMonthly() != null) {
            example.and().andEqualTo("monthly", attendGoOutRecordQuery.getMonthly());
        }
        if (attendGoOutRecordQuery.getDaily() != null) {
            example.and().andEqualTo("daily", attendGoOutRecordQuery.getDaily());
        }
        if (attendGoOutRecordQuery.getPunchTime() != null) {
            example.and().andEqualTo("punchTime", attendGoOutRecordQuery.getPunchTime());
        }
        if (attendGoOutRecordQuery.getLongitude() != null) {
            example.and().andLike("longitude", "%" + attendGoOutRecordQuery.getLongitude() + "%");
        }
        if (attendGoOutRecordQuery.getLatitude() != null) {
            example.and().andLike("latitude", "%" + attendGoOutRecordQuery.getLatitude() + "%");
        }
        if (attendGoOutRecordQuery.getLocation() != null) {
            example.and().andLike("location", "%" + attendGoOutRecordQuery.getLocation() + "%");
        }
        if (attendGoOutRecordQuery.getOutInstru() != null) {
            example.and().andLike("outInstru", "%" + attendGoOutRecordQuery.getOutInstru() + "%");
        }
        if (attendGoOutRecordQuery.getGmtCreateStart() != null &&
                attendGoOutRecordQuery.getGmtCreateEnd() != null) {
            example.and().andBetween("gmtCreate", attendGoOutRecordQuery.getGmtCreateStart(),
                    attendGoOutRecordQuery.getGmtCreateEnd());
        }
        if (attendGoOutRecordQuery.getCreateUserId() != null) {
            example.and().andLike("createUserId", "%" + attendGoOutRecordQuery.getCreateUserId() + "%");
        }
        if (attendGoOutRecordQuery.getGmtModifiedStart() != null &&
                attendGoOutRecordQuery.getGmtModifiedEnd() != null) {
            example.and().andBetween("gmtModified", attendGoOutRecordQuery.getGmtModifiedStart(),
                    attendGoOutRecordQuery.getGmtModifiedEnd());
        }
        if (attendGoOutRecordQuery.getModifiedUserId() != null) {
            example.and().andLike("modifiedUserId", "%" + attendGoOutRecordQuery.getModifiedUserId() + "%");
        }
        // 排序
        ExampleKit.setExampleOrder(example,attendGoOutRecordQuery.getOrders());
        return example;
    }
}




